<?php

namespace apiend\modules\business\models;

use Yii;
use yii\db\Exception;
use yii\helpers\Json;
use common\helpers\ArrayHelper;
use common\models\bill\Bill;
use common\models\bill\BillData;
use common\models\bill\BillType;
use common\models\rfid\Rfid;

/**
 * 票据信息录入模型
 *
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
class BillForm extends \common\base\Model {

    /**
     * @var integer 用户UID
     */
    public $user_id;

    /**
     * @var integer 用户UID
     */
    public $type_id;

    /**
     * @var integer 用户UID
     */
    public $company_id;

    /**
     * @var string 用户UID
     */
    public $bill_no;

    /**
     * @var string
     */
    public $data;

    /**
     * @var object 票据类型
     */
    private $_type = null;

    /**
     * @var array 票据类型
     */
    private $_fields = [];

    /**
     * {@inheritdoc}
     */
    public function rules() {
        return [
            [['bill_no', 'type_id'], 'required'],
            [['user_id', 'type_id'], 'integer'],
            [['bill_no'], 'string', 'max' => 32],
            [['data'], 'string'],
            [['type_id'], 'validateType'],
            [['data'], 'validateData'],
        ];
    }

    /**
     * Finds user by [[username]]
     *
     * @return \api\models\UserCompatibleModel|null
     */
    protected function getType() {
        if ($this->_type === null) {
            $query = BillType::find()->active(BillType::STATUS_ACTIVE)->andWhere([
                'id' => $this->type_id
            ]);
            Yii::error($query->debug());
            $this->_type = $query->one();
        }
        return $this->_type;
    }

    /**
     * 格式化地点
     */
    public function validateType($attribute) {
        if ($this->hasErrors()) {
            return;
        }
        $type = $this->getType();
        if ($type == null) {
            $this->addError($attribute, '需要指定写入的票据类型');
        }
    }

    /**
     * 格式化地点
     */
    public function validateData($attribute) {
        if ($this->hasErrors()) {
            return;
        }
        $type = $this->getType();
        $params = $type->params;
        if (empty($params)) {
            return;
        }
        $data = Json::decode($this->data);
        if (empty($data)) {
            $this->addError($attribute, '需要写入内容参数');
        }

        foreach ($params as $field) {
            $vls = ArrayHelper::getValue($data, $field->id);
            if ($field->required && empty($vls)) {
                $this->addError($attribute, '请输入' . $field->label . '的值');
                break;
            }
            $this->_fields[] = [
                'field_id' => $field->id,
                'data_type' => $field->data_type,
                'content' => $vls,
            ];
        }
    }

    /**
     * 保存动态信息（发布&修改）
     */
    public function save() {
        if (!$this->validate()) {
            return $this->dumpError('提交失败');
        }

        $nums = $this->type->quantity;

        $model = Bill::findOrNew([
            'bill_no' => $this->bill_no,
            'type_id' => $this->type_id,
            'company_id' => $this->company_id,
        ]);
        $model->user_id = $this->user_id;
        $model->nums = $nums;
        if (!$model->isNewRecord) {
            if ($model->status !== Bill::STATUS_DEFAULT) {
                return $this->dumpError('票据异常');
            }
            return $model->refreshBuildToken();
        }
        $model->generateBuildToken();

        $transaction = Yii::$app->db->beginTransaction();
        try {
            if (!$model->save()) {
                throw new Exception('票据信息保存失败');
            }

            if (!empty($this->_fields)) {
                $billDataModel = new BillData();
                foreach ($this->_fields as $field) {
                    $_billDataModel = clone $billDataModel;
                    $_billDataModel->setAttributes($field);
                    $_billDataModel->bill_id = $model->id;
                    if (!$_billDataModel->save()) {
                        throw new Exception('内容保存时失败');
                    }
                }
            }

            if ($nums > 0) {
                $rfid = new Rfid();
                for ($i = 0; $i < $nums; $i++) {
                    $_rfid = clone $rfid;
                    $_rfid->bill_id = $model->id;
                    $_rfid->setAttributes([
                        'company_id' => $this->type->company_id,
                        'status' => 0,
                    ]);
                    $_rfid->generateNo();
                    if (!$_rfid->save()) {
                        throw new Exception('标签生成失败');
                    }
                }
            }

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            return $this->dumpError($e->getMessage());
        }

        return $model->toArray();
    }

}
